﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestConsoleApp
{
    public class TestReaderWriterLock
    {

        static ReaderWriterLock rw = new ReaderWriterLock();
        static List<int> items = new List<int>();
        static Random rand = new Random();


        public static void Test()
        {
            new Thread(delegate ()
            {
                while (true)
                {
                    AppendItem();
                    Thread.Sleep(1000);
                }
            }).Start();
            new Thread(delegate ()
            {
                while (true)
                {
                    RemoveItem();
                    Thread.Sleep(1000);
                }
            }).Start();
            new Thread(delegate ()
            {
                while (true)
                {
                    WriteTotal();
                    Thread.Sleep(1000);
                }
            }).Start();
            new Thread(delegate ()
            {
                while (true)
                {
                    WriteTotal();
                    Thread.Sleep(1000);
                }
            }).Start();

            Console.ReadLine();
        }


        static int GetRandNum(int max) { lock (rand) return rand.Next(max); }

        static void WriteTotal()
        {
            rw.AcquireReaderLock(10000);
            int tot = 0; foreach (int i in items) tot += i;
            Console.WriteLine("WriteTotal:" + tot + "--datetime:" + DateTime.Now.ToString("HH:mm.ff"));
            rw.ReleaseReaderLock();
        }

        static void AppendItem()
        {
            rw.AcquireWriterLock(10000);
            items.Add(GetRandNum(1000));
            Thread.SpinWait(400);
            rw.ReleaseWriterLock();
        }

        static void RemoveItem()
        {
            rw.AcquireWriterLock(10000);
            if (items.Count > 0)
                items.RemoveAt(GetRandNum(items.Count));
            rw.ReleaseWriterLock();
        }

    }
}
